﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Mendel
{
    public static class Universe
    {
        private static List<Item> items=new List<Item>();

        private static ReaderWriterLockSlim listlock = new ReaderWriterLockSlim();

        private static List<Error> errors = new List<Error>();

        private static ReaderWriterLockSlim errorlock = new ReaderWriterLockSlim();

        public static void AddError(Exception e)
        {
            errorlock.EnterWriteLock();
            try
            {
                errors.Add(new Error(Task.CurrentId,e, DateTime.Now));
            }
            finally
            {
                errorlock.ExitWriteLock();
            }
        }

        public static void AddItem(Item item)
        {
            if (item.Constant)          // konstansok nem kerülhetnek be
                return;

            listlock.EnterWriteLock();
            try
            {
                items.Add(item);
            }
            catch (Exception e)
            {
                AddError(e);
            }
            finally
            {
                listlock.ExitWriteLock();
            }
        }

        // true-val tér vissza ha volt törlés
        public static bool RemoveItem(Item item)
        {
            if (item.Constant)
                return false;

            listlock.EnterWriteLock();
            try
            {
                return items.Remove(item);
            }
            catch (Exception e)
            {
                AddError(e);
                return false;
            }
            finally
            {
                listlock.ExitWriteLock();
            }
        }

        public static Item GetByName(string name)
        {
            listlock.EnterReadLock();
            try
            {
                return items.First(p => p.Name.Equals(name));
            }
            catch (InvalidOperationException)
            {
                return null;
            }
            catch (Exception e)
            {
                AddError(e);
                return null;
            }
            finally
            {
                listlock.ExitReadLock();
            }

        }

        public static List<Item> GetByType(DType type)
        {
            listlock.EnterReadLock();
            try
            {
                var tmp = items.Where(p => p.Type == type);
                return new List<Item>(tmp);
            }
            catch (Exception e)
            {
                AddError(e);
                return null;
            }
            finally
            {
                listlock.ExitReadLock();
            }

        }

        public static List<Error> GetByID(int id)
        {
            errorlock.EnterReadLock();
            try
            {
                var tmp = errors.Where(p => p.TaskId == id);
                return new List<Error>(tmp);
            }
            finally
            {
                errorlock.ExitReadLock();
            }

        }

        public static int GetErrorNumber()
        {
            errorlock.EnterReadLock();
            try
            {
                return errors.Count;
            }
            finally
            {
                errorlock.ExitReadLock();
            }
        }

        public static List<Error> GetAllErrors(bool erase=false)
        {
            errorlock.EnterReadLock();
            try
            {
                return new List<Error>(errors);
            }
            finally
            {
                if (erase)
                    errors.Clear();
                errorlock.ExitReadLock();
            }
        }

        public static List<Item> GetUniverse()
        {
            return items;
        }

    }
}
